package com.hsb.seckill.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hsb.seckill.dao.OrderDao;
import com.hsb.seckill.entity.Order;
import com.hsb.seckill.entity.SeckillGoods;
import com.hsb.seckill.entity.SeckillOrder;
import com.hsb.seckill.entity.User;
import com.hsb.seckill.exception.GlobalException;
import com.hsb.seckill.result.ResBeanEnum;
import com.hsb.seckill.service.GoodsService;
import com.hsb.seckill.service.OrderService;
import com.hsb.seckill.service.SeckillGoodsService;
import com.hsb.seckill.service.SeckillOrderService;
import com.hsb.seckill.utils.MD5Util;
import com.hsb.seckill.utils.UUIDUtil;
import com.hsb.seckill.vo.GoodsVo;
import com.hsb.seckill.vo.OrderDetailVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import sun.plugin.util.UIUtil;

import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * (Order)表服务实现类
 *
 * @author makejava
 * @since 2021-09-05 21:58:25
 */
@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements OrderService {
    @Resource
    private OrderDao orderDao;
    @Autowired
    private SeckillGoodsService seckillGoodsService;
    @Autowired
    private SeckillOrderService seckillOrderService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private GoodsService goodsService;
    /**
     * 秒杀，创建订单
     * @param user
     * @param goods
     * @return
     */
    @Override
    public Order sekill(User user, GoodsVo goods) {
        //根据商品id秒杀商品
        SeckillGoods seckillGoods = seckillGoodsService.getOne(new QueryWrapper<SeckillGoods>().eq("goods_id", goods.getId()));
        //秒杀商品库存减1
        //seckillGoods.setStockCount(seckillGoods.getStockCount()-1);
        //更新秒杀商品数据表
        //seckillGoodsService.updateById(seckillGoods);

        // 解决库存超卖
        boolean result = seckillGoodsService.update(new UpdateWrapper<SeckillGoods>().setSql("stock_count = stock_count-1").eq("goods_id", goods.getId()).gt("stock_count", 0));

        if (seckillGoods.getStockCount()<1){
            redisTemplate.opsForValue().set("isStockEmpty:"+goods.getId(),"0");
            return null;
        }
        //创建订单
        Order order = new Order();
        order.setUserId(user.getId());
        order.setGoodsId(goods.getId());
        order.setDeliveryAddrId(0L);
        order.setGoodsName(goods.getGoodsName());
        order.setGoodsCount(1);
        order.setGoodsPrice(seckillGoods.getSeckillPrice());
        order.setOrderChannel(1);
        order.setStatus(0);
        order.setCreateDate(new Date());
        orderDao.insert(order);
        //生产秒杀订单
        SeckillOrder seckillOrder = new SeckillOrder();
        seckillOrder.setUserId(user.getId());
        seckillOrder.setOrderId(order.getId());
        seckillOrder.setGoodsId(goods.getId());
        seckillOrderService.save(seckillOrder);

        // 将订单缓存到redis中
        redisTemplate.opsForValue().set(("order:"+user.getId()+":"+goods.getId()),seckillOrder);

        return order;
    }

    /**
     * 根据订单id查询订单详情
     * @param orderId
     * @return
     */
    @Override
    public OrderDetailVo detail(Long orderId) {
        if (orderId==null){
            throw new GlobalException(ResBeanEnum.ORDER_NOT_EXIST);
        }
        Order order = orderDao.selectById(orderId);
        GoodsVo goodsVo = goodsService.querySeckillGoodsById(order.getGoodsId());
        OrderDetailVo orderDetailVo = new OrderDetailVo();
        orderDetailVo.setOrder(order);
        orderDetailVo.setGoodsVo(goodsVo);
        return orderDetailVo;
    }

    /**
     * 获取秒杀地址
     * @param user
     * @param goodsId
     * @return
     */
    @Override
    public String getPath(User user, Long goodsId) {
        // 设置随机生成路径
        String s = MD5Util.md5(UUIDUtil.uuid() + "12345");
        // 存储到redis
        redisTemplate.opsForValue().set("seckillPath:"+user.getId()+":"+goodsId,s,60,TimeUnit.SECONDS );
        return s;
    }

    /**
     * 校验秒杀路径是否合法
     * @param user
     * @param goodsId
     * @param path
     * @return
     */
    @Override
    public Boolean checkPath(User user, long goodsId, String path) {
        if (user == null || goodsId <0 || StringUtils.isEmpty(path)){
            return false;
        }
        String str = (String) redisTemplate.opsForValue().get("seckillPath:"+user.getId()+":"+goodsId);
        return path.equals(str);
    }

    /**
     * 校验验证码
     * @param user
     * @param goodsId
     * @param captcha
     * @return
     */
    @Override
    public Boolean checkCaptcha(User user, Long goodsId, String captcha) {

        if (user == null || goodsId < 0 || StringUtils.isEmpty(captcha)){
            return false;
        }
        //从redis中获取验证码
        String s = (String) redisTemplate.opsForValue().get("captcha:"+user.getId()+":"+goodsId);

        return captcha.equals(s);
    }
}